home *** CD-ROM | disk | FTP | other *** search
- Subject: v23i024: The SC Spreadsheet, release 6.8, Part04/06
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: 7f9d9dff a2a6a7c7 ba0c427b cf2b77a6
-
- Submitted-by: Jeff Buhrt <sawmill!buhrt>
- Posting-number: Volume 23, Issue 24
- Archive-name: sc6.8/part04
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: cmds.c lex.c psc.c xmalloc.c
- # Wrapped by rsalz@litchi.bbn.com on Fri Jul 13 15:24:21 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 4 (of 6)."'
- if test -f 'cmds.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cmds.c'\"
- else
- echo shar: Extracting \"'cmds.c'\" \(30867 characters\)
- sed "s/^X//" >'cmds.c' <<'END_OF_FILE'
- X/* SC A Spreadsheet Calculator
- X * Command routines
- X *
- X * original by James Gosling, September 1982
- X * modifications by Mark Weiser and Bruce Israel,
- X * University of Maryland
- X *
- X * More mods Robert Bond, 12/86
- X *
- X * $Revision: 6.8 $
- X */
- X
- X#include <curses.h>
- X#if defined(BSD42) || defined(BSD43)
- X#include <sys/file.h>
- X#else
- X#include <fcntl.h>
- X#endif
- X#include "sc.h"
- X#include <signal.h>
- X#include <errno.h>
- X
- X#ifdef BSD42
- X#include <strings.h>
- X#else
- X#ifndef SYSIII
- X#include <string.h>
- X#endif
- X#endif
- X
- X#ifdef SYSV3
- Xextern void exit();
- X#else
- Xextern int exit();
- X#endif
- X
- Xextern int errno;
- X
- X#define DEFCOLDELIM ':'
- X
- Xvoid
- Xduprow()
- X{
- X if (currow >= maxrows - 1 || maxrow >= maxrows - 1) {
- X if (!growtbl(GROWROW, 0, 0))
- X return;
- X }
- X modflg++;
- X currow++;
- X openrow (currow);
- X for (curcol = 0; curcol <= maxcol; curcol++) {
- X register struct ent *p = *ATBL(tbl, currow - 1, curcol);
- X if (p) {
- X register struct ent *n;
- X n = lookat (currow, curcol);
- X (void)copyent ( n, p, 1, 0);
- X }
- X }
- X for (curcol = 0; curcol <= maxcol; curcol++) {
- X register struct ent *p = *ATBL(tbl, currow, curcol);
- X if (p && (p -> flags & is_valid) && !p -> expr)
- X break;
- X }
- X if (curcol > maxcol)
- X curcol = 0;
- X}
- X
- Xvoid
- Xdupcol()
- X{
- X if (curcol >= maxcols - 1 || maxcol >= maxcols - 1) {
- X if (!growtbl(GROWCOL, 0, 0))
- X return;
- X }
- X modflg++;
- X curcol++;
- X opencol (curcol, 1);
- X for (currow = 0; currow <= maxrow; currow++) {
- X register struct ent *p = *ATBL(tbl, currow, curcol - 1);
- X if (p) {
- X register struct ent *n;
- X n = lookat (currow, curcol);
- X copyent ( n, p, 0, 1);
- X }
- X }
- X for (currow = 0; currow <= maxrow; currow++) {
- X register struct ent *p = *ATBL(tbl, currow, curcol);
- X if (p && (p -> flags & is_valid) && !p -> expr)
- X break;
- X }
- X if (currow > maxrow)
- X currow = 0;
- X}
- X
- Xvoid
- Xinsertrow(arg)
- Xregister int arg;
- X{
- X while (--arg>=0) openrow (currow);
- X}
- X
- Xvoid
- Xdeleterow(arg)
- Xregister int arg;
- X{
- X flush_saved();
- X erase_area(currow, 0, currow + arg - 1, maxcol);
- X currow += arg;
- X while (--arg>=0) closerow (--currow);
- X sync_refs();
- X}
- X
- Xvoid
- Xrowvalueize(arg)
- Xregister int arg;
- X{
- X valueize_area(currow, 0, currow + arg - 1, maxcol);
- X}
- X
- Xvoid
- Xcolvalueize(arg)
- Xregister int arg;
- X{
- X valueize_area(0, curcol, maxrow, curcol + arg - 1);
- X}
- X
- Xvoid
- Xerase_area(sr, sc, er, ec)
- Xint sr, sc, er, ec;
- X{
- X register int r, c;
- X register struct ent **pp;
- X
- X if (sr > er) {
- X r = sr; sr = er; er= r;
- X }
- X
- X if (sc > ec) {
- X c = sc; sc = ec; ec= c;
- X }
- X
- X if (sr < 0)
- X sr = 0;
- X if (sc < 0)
- X sc = 0;
- X checkbounds(&er, &ec);
- X
- X for (r = sr; r <= er; r++) {
- X for (c = sc; c <= ec; c++) {
- X pp = ATBL(tbl, r, c);
- X if (*pp) {
- X free_ent(*pp);
- X *pp = (struct ent *)0;
- X }
- X }
- X }
- X}
- X
- Xvoid
- Xvalueize_area(sr, sc, er, ec)
- Xint sr, sc, er, ec;
- X{
- X register int r, c;
- X register struct ent *p;
- X
- X if (sr > er) {
- X r = sr; sr = er; er= r;
- X }
- X
- X if (sc > ec) {
- X c = sc; sc = ec; ec= c;
- X }
- X
- X if (sr < 0)
- X sr = 0;
- X if (sc < 0)
- X sc = 0;
- X checkbounds(&er, &ec);
- X
- X for (r = sr; r <= er; r++) {
- X for (c = sc; c <= ec; c++) {
- X p = *ATBL(tbl, r, c);
- X if (p && p->expr) {
- X efree(p, p->expr);
- X p->expr = (struct enode *)0;
- X p->flags &= ~is_strexpr;
- X }
- X }
- X }
- X
- X}
- X
- Xvoid
- Xpullcells(to_insert)
- Xint to_insert;
- X{
- X register struct ent *p, *n;
- X register int deltar, deltac;
- X int minrow, mincol;
- X int mxrow, mxcol;
- X int numrows, numcols;
- X
- X if (! to_fix)
- X {
- X error ("No data to pull");
- X return;
- X }
- X
- X minrow = maxrows;
- X mincol = maxcols;
- X mxrow = 0;
- X mxcol = 0;
- X
- X for (p = to_fix; p; p = p->next) {
- X if (p->row < minrow)
- X minrow = p->row;
- X if (p->row > mxrow)
- X mxrow = p->row;
- X if (p->col < mincol)
- X mincol = p->col;
- X if (p->col > mxcol)
- X mxcol = p->col;
- X }
- X
- X numrows = mxrow - minrow + 1;
- X numcols = mxcol - mincol + 1;
- X deltar = currow - minrow;
- X deltac = curcol - mincol;
- X
- X if (to_insert == 'r') {
- X insertrow(numrows);
- X deltac = 0;
- X } else if (to_insert == 'c') {
- X opencol(curcol, numcols);
- X deltar = 0;
- X }
- X
- X FullUpdate++;
- X modflg++;
- X
- X for (p = to_fix; p; p = p->next) {
- X n = lookat (p->row + deltar, p->col + deltac);
- X (void) clearent(n);
- X copyent( n, p, deltar, deltac);
- X n -> flags = p -> flags & ~is_deleted;
- X }
- X}
- X
- Xvoid
- Xcolshow_op()
- X{
- X register int i,j;
- X for (i=0; i<maxcols; i++)
- X if (col_hidden[i])
- X break;
- X for(j=i; j<maxcols; j++)
- X if (!col_hidden[j])
- X break;
- X j--;
- X if (i>=maxcols)
- X error ("No hidden columns to show");
- X else {
- X (void) sprintf(line,"show %s:", coltoa(i));
- X (void) sprintf(line + strlen(line),"%s",coltoa(j));
- X linelim = strlen (line);
- X }
- X}
- X
- Xvoid
- Xrowshow_op()
- X{
- X register int i,j;
- X for (i=0; i<maxrows; i++)
- X if (row_hidden[i])
- X break;
- X for(j=i; j<maxrows; j++)
- X if (!row_hidden[j]) {
- X break;
- X }
- X j--;
- X
- X if (i>=maxrows)
- X error ("No hidden rows to show");
- X else {
- X (void) sprintf(line,"show %d:%d", i, j);
- X linelim = strlen (line);
- X }
- X}
- X
- X/*
- X * Given a row/column command letter, emit a small menu, then read a qualifier
- X * character for a row/column command and convert it to 'r' (row), 'c'
- X * (column), or 0 (unknown). If ch is 'p', an extra qualifier 'm' is allowed.
- X */
- X
- Xint
- Xget_rcqual (ch)
- X int ch;
- X{
- X error ("%sow/column: r: row c: column%s",
- X
- X (ch == 'i') ? "Insert r" :
- X (ch == 'a') ? "Append r" :
- X (ch == 'd') ? "Delete r" :
- X (ch == 'p') ? "Pull r" :
- X (ch == 'v') ? "Values r" :
- X (ch == 'z') ? "Zap r" :
- X (ch == 's') ? "Show r" : "R",
- X
- X (ch == 'p') ? " m: merge" : "");
- X
- X (void) refresh();
- X
- X switch (nmgetch())
- X {
- X case 'r':
- X case 'l':
- X case 'h':
- X case ctl('f'):
- X case ctl('b'): return ('r');
- X
- X case 'c':
- X case 'j':
- X case 'k':
- X case ctl('p'):
- X case ctl('n'): return ('c');
- X
- X case 'm': return ((ch == 'p') ? 'm' : 0);
- X
- X case ESC:
- X case ctl('g'): return (ESC);
- X
- X default: return (0);
- X }
- X /*NOTREACHED*/
- X}
- X
- Xvoid
- Xopenrow (rs)
- Xint rs;
- X{
- X register r, c;
- X struct ent **tmprow, **pp;
- X
- X if (rs > maxrow) maxrow = rs;
- X if (maxrow >= maxrows - 1 || rs > maxrows - 1) {
- X if (!growtbl(GROWROW, rs, 0))
- X return;
- X }
- X /*
- X * save the last active row+1, shift the rows downward, put the last
- X * row in place of the first
- X */
- X tmprow = tbl[++maxrow];
- X for (r = maxrow; r > rs; r--) {
- X row_hidden[r] = row_hidden[r-1];
- X tbl[r] = tbl[r-1];
- X pp = ATBL(tbl, r, 0);
- X for (c = 0; c < maxcols; c++, pp++)
- X if (*pp)
- X (*pp)->row = r;
- X }
- X tbl[r] = tmprow; /* the last row was never used.... */
- X FullUpdate++;
- X modflg++;
- X}
- X
- Xvoid
- Xcloserow (r)
- Xregister r;
- X{
- X register struct ent **pp;
- X register c;
- X struct ent **tmprow;
- X
- X if (r > maxrow) return;
- X
- X /* save the row and empty it out */
- X tmprow = tbl[r];
- X pp = ATBL(tbl, r, 0);
- X for (c=maxcol+1; --c>=0; pp++) {
- X if (*pp)
- X { free_ent(*pp);
- X *pp = (struct ent *)0;
- X }
- X }
- X
- X /* move the rows, put the deleted row at the end */
- X for (; r < maxrows - 1; r++) {
- X row_hidden[r] = row_hidden[r+1];
- X tbl[r] = tbl[r+1];
- X pp = ATBL(tbl, r, 0);
- X for (c = 0; c < maxcols; c++, pp++)
- X if (*pp)
- X (*pp)->row = r;
- X }
- X tbl[r] = tmprow;
- X
- X maxrow--;
- X FullUpdate++;
- X modflg++;
- X}
- X
- Xvoid
- Xopencol (cs, numcol)
- Xint cs;
- Xint numcol;
- X{
- X register r;
- X register struct ent **pp;
- X register c;
- X register lim = maxcol-cs+1;
- X int i;
- X
- X if (cs > maxcol)
- X maxcol = cs;
- X maxcol += numcol;
- X
- X if ((maxcol >= maxcols - 1) && !growtbl(GROWCOL, 0, maxcol))
- X return;
- X
- X for (i = maxcol; i > cs; i--) {
- X fwidth[i] = fwidth[i-numcol];
- X precision[i] = precision[i-numcol];
- X col_hidden[i] = col_hidden[i-numcol];
- X }
- X for (c = cs; c - cs < numcol; c++)
- X { fwidth[c] = DEFWIDTH;
- X precision[c] = DEFPREC;
- X }
- X
- X for (r=0; r<=maxrow; r++) {
- X pp = ATBL(tbl, r, maxcol);
- X for (c=lim; --c>=0; pp--)
- X if (pp[0] = pp[-numcol])
- X pp[0]->col += numcol;
- X
- X pp = ATBL(tbl, r, cs);
- X for (c = cs; c - cs < numcol; c++, pp++)
- X *pp = (struct ent *)0;
- X }
- X FullUpdate++;
- X modflg++;
- X}
- X
- Xvoid
- Xclosecol (cs, numcol)
- Xint cs;
- Xint numcol;
- X{
- X register r;
- X register struct ent **pp;
- X register struct ent *q;
- X register c;
- X register lim = maxcol-cs;
- X int i;
- X char buf[50];
- X
- X if (lim - numcol < -1)
- X { sprintf(buf, "Can't delete %d column%s %d columns left", numcol,
- X (numcol > 1 ? "s," : ","), lim+1);
- X error(buf);
- X return;
- X }
- X flush_saved();
- X erase_area(0, curcol, maxrow, curcol + numcol - 1);
- X sync_refs();
- X
- X /* clear then copy the block left */
- X lim = maxcols - numcol - 1;
- X for (r=0; r<=maxrow; r++) {
- X for (c = cs; c - cs < numcol; c++)
- X if (q = *ATBL(tbl, r, c))
- X free_ent(q);
- X
- X pp = ATBL(tbl, r, cs);
- X for (c=cs; c <= lim; c++, pp++)
- X { if (c > lim)
- X *pp = (struct ent *)0;
- X else
- X if (pp[0] = pp[numcol])
- X pp[0]->col -= numcol;
- X }
- X
- X c = numcol;
- X for (; --c >= 0; pp++)
- X *pp = (struct ent *)0;
- X }
- X
- X for (i = cs; i < maxcols - numcol - 1; i++) {
- X fwidth[i] = fwidth[i+numcol];
- X precision[i] = precision[i+numcol];
- X col_hidden[i] = col_hidden[i+numcol];
- X }
- X for (; i < maxcols - 1; i++) {
- X fwidth[i] = DEFWIDTH;
- X precision[i] = DEFPREC;
- X col_hidden[i] = 0;
- X }
- X
- X maxcol -= numcol;
- X FullUpdate++;
- X modflg++;
- X}
- X
- Xvoid
- Xdoend(rowinc, colinc)
- Xint rowinc, colinc;
- X{
- X register struct ent *p;
- X int r, c;
- X
- X if (VALID_CELL(p, currow, curcol)) {
- X r = currow + rowinc;
- X c = curcol + colinc;
- X if (r >= 0 && r < maxrows &&
- X c >= 0 && c < maxcols &&
- X !VALID_CELL(p, r, c)) {
- X currow = r;
- X curcol = c;
- X }
- X }
- X
- X if (!VALID_CELL(p, currow, curcol)) {
- X switch (rowinc) {
- X case -1:
- X while (!VALID_CELL(p, currow, curcol) && currow > 0)
- X currow--;
- X break;
- X case 1:
- X while (!VALID_CELL(p, currow, curcol) && currow < maxrows-1)
- X currow++;
- X break;
- X case 0:
- X switch (colinc) {
- X case -1:
- X while (!VALID_CELL(p, currow, curcol) && curcol > 0)
- X curcol--;
- X break;
- X case 1:
- X while (!VALID_CELL(p, currow, curcol) && curcol < maxcols-1)
- X curcol++;
- X break;
- X }
- X break;
- X }
- X
- X error (""); /* clear line */
- X return;
- X }
- X
- X switch (rowinc) {
- X case -1:
- X while (VALID_CELL(p, currow, curcol) && currow > 0)
- X currow--;
- X break;
- X case 1:
- X while (VALID_CELL(p, currow, curcol) && currow < maxrows-1)
- X currow++;
- X break;
- X case 0:
- X switch (colinc) {
- X case -1:
- X while (VALID_CELL(p, currow, curcol) && curcol > 0)
- X curcol--;
- X break;
- X case 1:
- X while (VALID_CELL(p, currow, curcol) && curcol < maxcols-1)
- X curcol++;
- X break;
- X }
- X break;
- X }
- X if (!VALID_CELL(p, currow, curcol)) {
- X currow -= rowinc;
- X curcol -= colinc;
- X }
- X}
- X
- Xvoid
- Xdoformat(c1,c2,w,p)
- Xint c1,c2,w,p;
- X{
- X register int i;
- X
- X if (w > COLS - RESCOL - 2) {
- X error("Format too large - Maximum = %d", COLS - RESCOL - 2);
- X w = COLS-RESCOL-2;
- X }
- X
- X if (p > w) {
- X error("Precision too large");
- X p = w;
- X }
- X
- X for(i = c1; i<=c2; i++)
- X fwidth[i] = w, precision[i] = p;
- X
- X FullUpdate++;
- X modflg++;
- X}
- X
- Xvoid
- Xprint_options(f)
- XFILE *f;
- X{
- X if(
- X autocalc &&
- X propagation == 10 &&
- X calc_order == BYROWS &&
- X !numeric &&
- X prescale == 1.0 &&
- X !extfunc &&
- X showcell &&
- X showtop &&
- X tbl_style == 0
- X )
- X return; /* No reason to do this */
- X
- X (void) fprintf(f, "set");
- X if(!autocalc)
- X (void) fprintf(f," !autocalc");
- X if(propagation != 10)
- X (void) fprintf(f, " iterations = %d", propagation);
- X if(calc_order != BYROWS )
- X (void) fprintf(f, " bycols");
- X if (numeric)
- X (void) fprintf(f, " numeric");
- X if (prescale != 1.0)
- X (void) fprintf(f, " prescale");
- X if (extfunc)
- X (void) fprintf(f, " extfun");
- X if (!showcell)
- X (void) fprintf(f, " !cellcur");
- X if (!showtop)
- X (void) fprintf(f, " !toprow");
- X if (tbl_style)
- X (void) fprintf(f, " tblstyle = %s", tbl_style == TBL ? "tbl" :
- X tbl_style == LATEX ? "latex" :
- X tbl_style == TEX ? "tex" : "0" );
- X (void) fprintf(f, "\n");
- X}
- X
- Xvoid
- Xprintfile (fname, r0, c0, rn, cn)
- Xchar *fname;
- Xint r0, c0, rn, cn;
- X{
- X FILE *f;
- X char pline[FBUFLEN];
- X int plinelim;
- X int pid;
- X int fieldlen, nextcol;
- X register row, col;
- X register struct ent **pp;
- X
- X if ((strcmp(fname, curfile) == 0) &&
- X !yn_ask("Confirm that you want to destroy the data base: (y,n)"))
- X return;
- X
- X if ((f = openout(fname, &pid)) == (FILE *)0)
- X { error ("Can't create file \"%s\"", fname);
- X return;
- X }
- X for (row=r0;row<=rn; row++) {
- X register c = 0;
- X
- X if (row_hidden[row])
- X continue;
- X
- X pline[plinelim=0] = '\0';
- X for (pp = ATBL(tbl, row, col=c0); col<=cn;
- X pp += nextcol-col, col = nextcol, c += fieldlen) {
- X
- X nextcol = col+1;
- X if (col_hidden[col]) {
- X fieldlen = 0;
- X continue;
- X }
- X
- X fieldlen = fwidth[col];
- X if (*pp) {
- X char *s;
- X
- X while (plinelim<c) pline[plinelim++] = ' ';
- X plinelim = c;
- X if ((*pp)->flags&is_valid) {
- X (void)sprintf (pline+plinelim,"%*.*f",fwidth[col],
- X precision[col], (*pp)->v);
- X plinelim += strlen (pline+plinelim);
- X }
- X if (s = (*pp)->label) {
- X int slen;
- X char *start, *last;
- X register char *fp;
- X struct ent *nc;
- X
- X /* Figure out if the label slops over to a blank field */
- X slen = strlen(s);
- X while (slen > fieldlen && nextcol <= cn &&
- X !((nc = lookat(row,nextcol))->flags & is_valid) &&
- X !(nc->label)) {
- X
- X if (!col_hidden[nextcol])
- X fieldlen += fwidth[nextcol];
- X
- X nextcol++;
- X }
- X if (slen > fieldlen)
- X slen = fieldlen;
- X
- X /* Now justify and print */
- X start = (*pp)->flags & is_leftflush ? pline + c
- X : pline + c + fieldlen - slen;
- X last = pline + c + fieldlen;
- X fp = plinelim < c ? pline + plinelim : pline + c;
- X while (fp < start)
- X *fp++ = ' ';
- X while (slen--)
- X *fp++ = *s++;
- X if (!((*pp)->flags & is_valid) || fieldlen != fwidth[col])
- X while(fp < last)
- X *fp++ = ' ';
- X if (plinelim < fp - pline)
- X plinelim = fp - pline;
- X }
- X }
- X }
- X pline[plinelim++] = '\n';
- X pline[plinelim] = '\0';
- X (void) fputs (pline, f);
- X }
- X
- X closeout(f, pid);
- X}
- X
- Xvoid
- Xtblprintfile (fname, r0, c0, rn, cn)
- Xchar *fname;
- Xint r0, c0, rn, cn;
- X{
- X FILE *f;
- X int pid;
- X register row, col;
- X register struct ent **pp;
- X char coldelim = DEFCOLDELIM;
- X
- X if ((strcmp(fname, curfile) == 0) &&
- X !yn_ask("Confirm that you want to destroy the data base: (y,n)"))
- X return;
- X
- X if ((f = openout(fname, &pid)) == (FILE *)0)
- X { error ("Can't create file \"%s\"", fname);
- X return;
- X }
- X
- X if ( tbl_style == TBL ) {
- X fprintf(f,".\\\" ** %s spreadsheet output \n.TS\n",progname);
- X fprintf(f,"tab(%c);\n",coldelim);
- X for (col=c0;col<=cn; col++) fprintf(f," n");
- X fprintf(f, ".\n");
- X }
- X else if ( tbl_style == LATEX ) {
- X fprintf(f,"%% ** %s spreadsheet output\n\\begin{tabular}{",progname);
- X for (col=c0;col<=cn; col++) fprintf(f,"c");
- X fprintf(f, "}\n");
- X coldelim = '&';
- X }
- X else if ( tbl_style == TEX ) {
- X fprintf(f,"{\t%% ** %s spreadsheet output\n\\settabs %d \\columns\n",
- X progname, cn-c0+1);
- X coldelim = '&';
- X }
- X
- X for (row=r0; row<=rn; row++) {
- X if ( tbl_style == TEX )
- X (void) fprintf (f, "\\+");
- X
- X for (pp = ATBL(tbl, row, col=c0); col<=cn; col++, pp++) {
- X if (*pp) {
- X char *s;
- X if ((*pp)->flags&is_valid) {
- X (void) fprintf (f,"%.*f",precision[col],
- X (*pp)->v);
- X }
- X if (s = (*pp)->label) {
- X (void) fprintf (f,"%s",s);
- X }
- X }
- X if ( col < cn )
- X (void) fprintf(f,"%c",coldelim);
- X }
- X if ( tbl_style == LATEX ) {
- X if ( row < rn ) (void) fprintf (f, "\\\\");
- X }
- X else if ( tbl_style == TEX ) {
- X (void) fprintf (f, "\\cr");
- X }
- X (void) fprintf (f,"\n");
- X }
- X
- X if ( tbl_style == TBL )
- X (void) fprintf (f,".TE\n.\\\" ** end of %s spreadsheet output\n", progname);
- X else if ( tbl_style == LATEX )
- X (void) fprintf (f,"\\end{tabular}\n%% ** end of %s spreadsheet output\n", progname);
- X else if ( tbl_style == TEX )
- X (void) fprintf (f,"}\n%% ** end of %s spreadsheet output\n", progname);
- X
- X closeout(f, pid);
- X}
- X
- Xstruct enode *
- Xcopye (e, Rdelta, Cdelta)
- Xregister struct enode *e;
- Xint Rdelta, Cdelta;
- X{
- X register struct enode *ret;
- X
- X if (e == (struct enode *)0) {
- X ret = (struct enode *)0;
- X } else if (e->op & REDUCE) {
- X int newrow, newcol;
- X ret = (struct enode *) xmalloc ((unsigned) sizeof (struct enode));
- X ret->op = e->op;
- X newrow=e->e.r.left.vf & FIX_ROW ? e->e.r.left.vp->row :
- X e->e.r.left.vp->row+Rdelta;
- X newcol=e->e.r.left.vf & FIX_COL ? e->e.r.left.vp->col :
- X e->e.r.left.vp->col+Cdelta;
- X ret->e.r.left.vp = lookat (newrow, newcol);
- X ret->e.r.left.vf = e->e.r.left.vf;
- X newrow=e->e.r.right.vf & FIX_ROW ? e->e.r.right.vp->row :
- X e->e.r.right.vp->row+Rdelta;
- X newcol=e->e.r.right.vf & FIX_COL ? e->e.r.right.vp->col :
- X e->e.r.right.vp->col+Cdelta;
- X ret->e.r.right.vp = lookat (newrow, newcol);
- X ret->e.r.right.vf = e->e.r.right.vf;
- X } else {
- X ret = (struct enode *) xmalloc ((unsigned) sizeof (struct enode));
- X ret->op = e->op;
- X switch (ret->op) {
- X case 'v':
- X {
- X int newrow, newcol;
- X newrow=e->e.v.vf & FIX_ROW ? e->e.v.vp->row :
- X e->e.v.vp->row+Rdelta;
- X newcol=e->e.v.vf & FIX_COL ? e->e.v.vp->col :
- X e->e.v.vp->col+Cdelta;
- X ret->e.v.vp = lookat (newrow, newcol);
- X ret->e.v.vf = e->e.v.vf;
- X break;
- X }
- X case 'k':
- X ret->e.k = e->e.k;
- X break;
- X case 'f':
- X ret->e.o.right = copye (e->e.o.right,0,0);
- X ret->e.o.left = (struct enode *)0;
- X break;
- X case '$':
- X ret->e.s = xmalloc((unsigned) strlen(e->e.s)+1);
- X (void) strcpy(ret->e.s, e->e.s);
- X break;
- X default:
- X ret->e.o.right = copye (e->e.o.right,Rdelta,Cdelta);
- X ret->e.o.left = copye (e->e.o.left,Rdelta,Cdelta);
- X break;
- X }
- X }
- X return ret;
- X}
- X
- X/*
- X * sync_refs and syncref are used to remove references to
- X * deleted struct ents. Note that the deleted structure must still
- X * be hanging around before the call, but not referenced by an entry
- X * in tbl. Thus the free_ent, fix_ent calls in sc.c
- X */
- Xvoid
- Xsync_refs ()
- X{
- X register i,j;
- X register struct ent *p;
- X sync_ranges();
- X for (i=0; i<=maxrow; i++)
- X for (j=0; j<=maxcol; j++)
- X if ((p = *ATBL(tbl, i, j)) && p->expr)
- X syncref(p->expr);
- X}
- X
- Xvoid
- Xsyncref(e)
- Xregister struct enode *e;
- X{
- X if (e == (struct enode *)0)
- X return;
- X else if (e->op & REDUCE) {
- X e->e.r.right.vp = lookat(e->e.r.right.vp->row, e->e.r.right.vp->col);
- X e->e.r.left.vp = lookat(e->e.r.left.vp->row, e->e.r.left.vp->col);
- X } else {
- X switch (e->op) {
- X case 'v':
- X e->e.v.vp = lookat(e->e.v.vp->row, e->e.v.vp->col);
- X break;
- X case 'k':
- X break;
- X case '$':
- X break;
- X default:
- X syncref(e->e.o.right);
- X syncref(e->e.o.left);
- X break;
- X }
- X }
- X}
- X
- Xvoid
- Xhiderow(arg)
- Xint arg;
- X{
- X register int r1;
- X register int r2;
- X
- X r1 = currow;
- X r2 = r1 + arg - 1;
- X if (r1 < 0 || r1 > r2) {
- X error ("Invalid range");
- X return;
- X }
- X if (r2 >= maxrows-1)
- X { if (!growtbl(GROWROW, arg+1, 0))
- X { error("You can't hide the last row");
- X return;
- X }
- X }
- X FullUpdate++;
- X modflg++;
- X while (r1 <= r2)
- X row_hidden[r1++] = 1;
- X}
- X
- Xvoid
- Xhidecol(arg)
- Xint arg;
- X{
- X register int c1;
- X register int c2;
- X
- X c1 = curcol;
- X c2 = c1 + arg - 1;
- X if (c1 < 0 || c1 > c2) {
- X error ("Invalid range");
- X return;
- X }
- X if (c2 >= maxcols-1)
- X { if ((arg >= ABSMAXCOLS-1) || !growtbl(GROWCOL, 0, arg+1))
- X { error("You can't hide the last col");
- X return;
- X }
- X }
- X FullUpdate++;
- X modflg++;
- X while (c1 <= c2)
- X col_hidden[c1++] = 1;
- X}
- X
- Xvoid
- Xshowrow(r1, r2)
- Xint r1, r2;
- X{
- X if (r1 < 0 || r1 > r2) {
- X error ("Invalid range");
- X return;
- X }
- X if (r2 > maxrows-1) {
- X r2 = maxrows-1;
- X }
- X FullUpdate++;
- X modflg++;
- X while (r1 <= r2)
- X row_hidden[r1++] = 0;
- X}
- X
- Xvoid
- Xshowcol(c1, c2)
- Xint c1, c2;
- X{
- X if (c1 < 0 || c1 > c2) {
- X error ("Invalid range");
- X return;
- X }
- X if (c2 > maxcols-1) {
- X c2 = maxcols-1;
- X }
- X FullUpdate++;
- X modflg++;
- X while (c1 <= c2)
- X col_hidden[c1++] = 0;
- X}
- X
- X/* Open the output file, setting up a pipe if needed */
- X
- XFILE *
- Xopenout(fname, rpid)
- Xchar *fname;
- Xint *rpid;
- X{
- X int pipefd[2];
- X int pid;
- X FILE *f;
- X char *efname;
- X
- X while (*fname && (*fname == ' ')) /* Skip leading blanks */
- X fname++;
- X
- X if (*fname != '|') { /* Open file if not pipe */
- X *rpid = 0;
- X
- X efname = findhome(fname);
- X#ifdef DOBACKUPS
- X if (!backup_file(efname) &&
- X (yn_ask("Could not create backup copy, Save anyhow?: (y,n)") != 1))
- X return(0);
- X#endif
- X return(fopen(efname, "w"));
- X }
- X
- X fname++; /* Skip | */
- X if ( pipe (pipefd) < 0) {
- X error("Can't make pipe to child");
- X *rpid = 0;
- X return(0);
- X }
- X
- X deraw();
- X#ifdef VMS
- X fprintf(stderr, "No son tasks available yet under VMS--sorry\n");
- X#else /* VMS */
- X
- X if ((pid=fork()) == 0) /* if child */
- X {
- X (void) close (0); /* close stdin */
- X (void) close (pipefd[1]);
- X (void) dup (pipefd[0]); /* connect to pipe input */
- X (void) signal (SIGINT, SIG_DFL); /* reset */
- X (void) execl ("/bin/sh", "sh", "-c", fname, 0);
- X exit (-127);
- X }
- X else /* else parent */
- X {
- X *rpid = pid;
- X if ((f = fdopen (pipefd[1], "w")) == (FILE *)0)
- X {
- X (void) kill (pid, -9);
- X error ("Can't fdopen output");
- X (void) close (pipefd[1]);
- X *rpid = 0;
- X return(0);
- X }
- X }
- X#endif /* VMS */
- X return(f);
- X}
- X
- Xvoid
- Xcloseout(f, pid)
- XFILE *f;
- Xint pid;
- X{
- X int temp;
- X
- X (void) fclose (f);
- X if (pid) {
- X while (pid != wait(&temp)) /**/;
- X (void) printf("Press RETURN to continue ");
- X (void) fflush(stdout);
- X (void) nmgetch();
- X goraw();
- X }
- X}
- X
- Xvoid
- Xcopyent(n,p,dr,dc)
- X register struct ent *n, *p;
- X int dr, dc;
- X{
- X if(!n||!p){error("internal error");return;}
- X n -> v = p -> v;
- X n -> flags = p -> flags;
- X n -> expr = copye (p -> expr, dr, dc);
- X n -> label = (char *)0;
- X if (p -> label) {
- X n -> label = (char *)
- X xmalloc ((unsigned) (strlen (p -> label) + 1));
- X (void) strcpy (n -> label, p -> label);
- X }
- X}
- X
- Xvoid
- Xwrite_fd (f, r0, c0, rn, cn)
- Xregister FILE *f;
- Xint r0, c0, rn, cn;
- X{
- X register struct ent **pp;
- X register r, c;
- X
- X (void) fprintf (f, "# This data file was generated by the Spreadsheet ");
- X (void) fprintf (f, "Calculator.\n");
- X (void) fprintf (f, "# You almost certainly shouldn't edit it.\n\n");
- X print_options(f);
- X for (c=0; c<maxcols; c++)
- X if (fwidth[c] != DEFWIDTH || precision[c] != DEFPREC)
- X (void) fprintf (f, "format %s %d %d\n",coltoa(c),fwidth[c],precision[c]);
- X for (c=c0; c<cn; c++) {
- X if (col_hidden[c]) {
- X (void) fprintf(f, "hide %s\n", coltoa(c));
- X }
- X }
- X for (r=r0; r<=rn; r++) {
- X if (row_hidden[r]) {
- X (void) fprintf(f, "hide %d\n", r);
- X }
- X }
- X
- X write_range(f);
- X
- X if (mdir)
- X (void) fprintf(f, "mdir \"%s\"\n", mdir);
- X for (r=r0; r<=rn; r++) {
- X pp = ATBL(tbl, r, c0);
- X for (c=c0; c<=cn; c++, pp++)
- X if (*pp) {
- X if ((*pp)->label) {
- X edits(r,c);
- X (void) fprintf(f, "%s\n",line);
- X }
- X if ((*pp)->flags&is_valid) {
- X editv (r, c);
- X (void) fprintf (f, "%s\n",line);
- X }
- X }
- X }
- X}
- X
- Xint
- Xwritefile (fname, r0, c0, rn, cn)
- Xchar *fname;
- Xint r0, c0, rn, cn;
- X{
- X register FILE *f;
- X char save[PATHLEN];
- X int pid;
- X
- X#ifndef VMS
- X if (Crypt) {
- X return (cwritefile(fname, r0, c0, rn, cn));
- X }
- X#endif /* VMS */
- X
- X if (*fname == '\0') fname = curfile;
- X
- X (void) strcpy(save,fname);
- X
- X if ((f= openout(fname, &pid)) == (FILE *)0)
- X { error ("Can't create file \"%s\"", fname);
- X return (-1);
- X }
- X
- X write_fd(f, r0, c0, rn, cn);
- X
- X closeout(f, pid);
- X
- X if (!pid) {
- X (void) strcpy(curfile, save);
- X modflg = 0;
- X error("File \"%s\" written.",curfile);
- X }
- X
- X return (0);
- X}
- X
- Xvoid
- Xreadfile (fname,eraseflg)
- Xchar *fname;
- Xint eraseflg;
- X{
- X register FILE *f;
- X char save[PATHLEN];
- X
- X if (*fname == '*' && mdir) {
- X (void) strcpy(save, mdir);
- X *fname = '/';
- X (void) strcat(save, fname);
- X } else {
- X if (*fname == '\0')
- X fname = curfile;
- X (void) strcpy(save,fname);
- X }
- X
- X#ifndef VMS
- X if (Crypt) {
- X creadfile(save, eraseflg);
- X return;
- X }
- X#endif /* VMS */
- X
- X if (eraseflg && strcmp(fname,curfile) && modcheck(" first")) return;
- X
- X if ((f = fopen(findhome(save), "r")) == (FILE *)0)
- X { error ("Can't read file \"%s\"", save);
- X return;
- X }
- X
- X if (eraseflg) erasedb ();
- X
- X loading++;
- X while (fgets(line,sizeof line,f)) {
- X linelim = 0;
- X if (line[0] != '#') (void) yyparse ();
- X }
- X --loading;
- X (void) fclose (f);
- X linelim = -1;
- X modflg++;
- X if (eraseflg) {
- X (void) strcpy(curfile,save);
- X modflg = 0;
- X }
- X EvalAll();
- X}
- X
- Xvoid
- Xerasedb ()
- X{
- X register r, c;
- X for (c = 0; c<=maxcol; c++) {
- X fwidth[c] = DEFWIDTH;
- X precision[c] = DEFPREC;
- X }
- X
- X for (r = 0; r<=maxrow; r++) {
- X register struct ent **pp = ATBL(tbl, r, 0);
- X for (c=0; c++<=maxcol; pp++)
- X if (*pp) {
- X if ((*pp)->expr) efree (*pp, (*pp) -> expr);
- X if ((*pp)->label) xfree ((char *)((*pp) -> label));
- X xfree ((char *)(*pp));
- X *pp = (struct ent *)0;
- X }
- X }
- X maxrow = 0;
- X maxcol = 0;
- X clean_range();
- X FullUpdate++;
- X}
- X
- Xvoid
- Xbackcol(arg)
- X int arg;
- X{
- X while (--arg>=0) {
- X if (curcol)
- X curcol--;
- X else
- X {error ("At column A"); break;}
- X while(col_hidden[curcol] && curcol)
- X curcol--;
- X }
- X}
- X
- Xvoid
- Xforwcol(arg)
- X int arg;
- X{
- X while (--arg>=0) {
- X if (curcol < maxcols - 1)
- X curcol++;
- X else
- X if (!growtbl(GROWCOL, 0, arg)) /* get as much as needed */
- X break;
- X while(col_hidden[curcol]&&(curcol<maxcols-1))
- X curcol++;
- X }
- X}
- X
- Xvoid
- Xforwrow(arg)
- X int arg;
- X{
- X while (--arg>=0) {
- X if (currow < maxrows - 1)
- X currow++;
- X else
- X if (!growtbl(GROWROW, arg, 0)) /* get as much as needed */
- X break;
- X while (row_hidden[currow]&&(currow<maxrows-1))
- X currow++;
- X }
- X}
- X
- Xvoid
- Xbackrow(arg)
- X int arg;
- X{
- X while (--arg>=0) {
- X if (currow)
- X currow--;
- X else
- X {error ("At row zero"); break;}
- X while (row_hidden[currow] && currow)
- X currow--;
- X }
- X}
- X
- X
- X/*
- X * Show a cell's label string or expression value. May overwrite value if
- X * there is one already displayed in the cell. Created from old code in
- X * update(), copied with minimal changes.
- X */
- X
- Xvoid
- Xshowstring (string, leftflush, hasvalue, row, col, nextcolp, mxcol, fieldlenp, r, c)
- X char *string; /* to display */
- X int leftflush; /* or rightflush */
- X int hasvalue; /* is there a numeric value? */
- X int row, col; /* spreadsheet location */
- X int *nextcolp; /* value returned through it */
- X int mxcol; /* last column displayed? */
- X int *fieldlenp; /* value returned through it */
- X int r, c; /* screen row and column */
- X{
- X register int nextcol = *nextcolp;
- X register int fieldlen = *fieldlenp;
- X
- X char field[FBUFLEN];
- X int slen;
- X char *start, *last;
- X register char *fp;
- X struct ent *nc;
- X
- X /* This figures out if the label is allowed to
- X slop over into the next blank field */
- X
- X slen = strlen (string);
- X while ((slen > fieldlen) && (nextcol <= mxcol) &&
- X !((nc = lookat (row, nextcol)) -> flags & is_valid) &&
- X !(nc->label)) {
- X
- X if (! col_hidden [nextcol])
- X fieldlen += fwidth [nextcol];
- X
- X nextcol++;
- X }
- X if (slen > fieldlen)
- X slen = fieldlen;
- X
- X /* Now justify and print */
- X start = leftflush ? field : field + fieldlen - slen;
- X last = field+fieldlen;
- X fp = field;
- X while (fp < start)
- X *fp++ = ' ';
- X while (slen--)
- X *fp++ = *string++;
- X if ((! hasvalue) || fieldlen != fwidth[col])
- X while (fp < last)
- X *fp++ = ' ';
- X *fp = '\0';
- X#ifdef VMS
- X mvaddstr(r, c, field); /* this is a macro */
- X#else
- X (void) mvaddstr(r, c, field);
- X#endif
- X
- X *nextcolp = nextcol;
- X *fieldlenp = fieldlen;
- X}
- X
- Xint
- Xetype(e)
- Xregister struct enode *e;
- X{
- X if (e == (struct enode *)0)
- X return NUM;
- X switch (e->op) {
- X case O_SCONST: case '#': case DATE: case FMT: case STINDEX:
- X case EXT: case SVAL: case SUBSTR:
- X return (STR);
- X
- X case '?':
- X case IF:
- X return(etype(e->e.o.right->e.o.left));
- X
- X case 'f':
- X return(etype(e->e.o.right));
- X
- X case O_VAR: {
- X register struct ent *p;
- X p = e->e.v.vp;
- X if (p->expr)
- X return(p->flags & is_strexpr ? STR : NUM);
- X else if (p->label)
- X return(STR);
- X else
- X return(NUM);
- X }
- X
- X default:
- X return(NUM);
- X }
- X}
- X
- X/* return 1 if yes given, 0 otherwise */
- Xint
- Xyn_ask(msg)
- Xchar *msg;
- X{ char ch;
- X
- X (void) move (0, 0);
- X (void) clrtoeol ();
- X (void) addstr (msg);
- X (void) refresh();
- X ch = nmgetch();
- X if ( ch != 'y' && ch != 'Y' && ch != 'n' && ch != 'N' ) {
- X if (ch == ctl('g') || ch == ESC)
- X return(-1);
- X error("y or n response required");
- X return (-1);
- X }
- X if (ch == 'y' || ch == 'Y')
- X return(1);
- X else
- X return(0);
- X}
- X
- X#include <pwd.h>
- Xchar *
- Xfindhome(path)
- Xchar *path;
- X{
- X static char *HomeDir = NULL;
- X extern char *getenv();
- X
- X if (*path == '~')
- X { char *pathptr;
- X char tmppath[PATHLEN];
- X
- X if (HomeDir == NULL)
- X { HomeDir = getenv("HOME");
- X if (HomeDir == NULL)
- X HomeDir = "/";
- X }
- X pathptr = path + 1;
- X if ((*pathptr == '/') || (*pathptr == '\0'))
- X { strcpy(tmppath, HomeDir);
- X }
- X else
- X { struct passwd *pwent;
- X extern struct passwd *getpwnam();
- X char *namep;
- X char name[50];
- X
- X namep = name;
- X while ((*pathptr != '\0') && (*pathptr != '/'))
- X *(namep++) = *(pathptr++);
- X *namep = '\0';
- X if ((pwent = getpwnam(name)) == NULL)
- X { sprintf(path, "Can't find user %s", name);
- X return(NULL);
- X }
- X strcpy(tmppath, pwent->pw_dir);
- X }
- X
- X strcat(tmppath, pathptr);
- X strcpy(path, tmppath);
- X }
- X return(path);
- X}
- X
- X#ifdef DOBACKUPS
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X/*
- X * make a backup copy of a file, use the same mode and name in the format
- X * [path/]#file~
- X * return 1 if we were successful, 0 otherwise
- X */
- Xint
- Xbackup_file(path)
- Xchar *path;
- X{
- X struct stat statbuf;
- X char fname[PATHLEN];
- X char tpath[PATHLEN];
- X#ifdef sequent
- X char *buf;
- X#else
- X char buf[BUFSIZ];
- X#endif
- X char *tpp;
- X int infd, outfd;
- X int count;
- X
- X /* tpath will be the [path/]file ---> [path/]#file~ */
- X strcpy(tpath, path);
- X if ((tpp = strrchr(tpath, '/')) == NULL)
- X tpp = tpath;
- X else
- X tpp++;
- X strcpy(fname, tpp);
- X sprintf(tpp, "#%s~", fname);
- X
- X if (stat(path, &statbuf) == 0)
- X {
- X#ifdef sequent
- X if ((buf = xmalloc(statbuf.st_blksize)) == (char *)0)
- X return(0);
- X#endif
- X
- X if ((infd = open(path, O_RDONLY, 0)) < 0)
- X {
- X#ifdef sequent
- X xfree(buf);
- X#endif
- X return(0);
- X }
- X if ((outfd = open(tpath, O_TRUNC|O_WRONLY|O_CREAT,
- X statbuf.st_mode)) < 0)
- X {
- X#ifdef sequent
- X xfree(buf);
- X#endif
- X return(0);
- X }
- X#ifdef sequent
- X while((count = read(infd, buf, statbuf.st_blksize)) > 0)
- X#else
- X while((count = read(infd, buf, sizeof(buf))) > 0)
- X#endif
- X { if (write(outfd, buf, count) != count)
- X { count = -1;
- X break;
- X }
- X }
- X close(infd);
- X close(outfd);
- X#ifdef sequent
- X xfree(buf);
- X#endif
- X return((count < 0) ? 0 : 1);
- X }
- X else
- X if (errno == ENOENT)
- X return(1);
- X return(0);
- X}
- X#endif
- END_OF_FILE
- if test 30867 -ne `wc -c <'cmds.c'`; then
- echo shar: \"'cmds.c'\" unpacked with wrong size!
- fi
- # end of 'cmds.c'
- fi
- if test -f 'lex.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lex.c'\"
- else
- echo shar: Extracting \"'lex.c'\" \(13128 characters\)
- sed "s/^X//" >'lex.c' <<'END_OF_FILE'
- X/* SC A Spreadsheet Calculator
- X * Lexical analyser
- X *
- X * original by James Gosling, September 1982
- X * modifications by Mark Weiser and Bruce Israel,
- X * University of Maryland
- X *
- X * More mods Robert Bond, 12/86
- X * More mods by Alan Silverstein, 3/88, see list of changes.
- X * $Revision: 6.8 $
- X *
- X */
- X
- X
- X
- X#if defined(BSD42) || defined(BSD43)
- X#include <sys/ioctl.h>
- X#endif
- X
- X#ifdef IEEE_MATH
- X#include <ieeefp.h>
- X#endif /* IEEE_MATH */
- X
- X#include <curses.h>
- X#include <signal.h>
- X#include <setjmp.h>
- X#include "sc.h"
- X#include <ctype.h>
- X
- X#ifdef BSD42
- X#include <strings.h>
- X#else
- X#ifndef SYSIII
- X#include <string.h>
- X#endif
- X#endif
- X
- X#ifdef VMS
- X#include "gram_tab.h"
- Xtypedef union {
- X int ival;
- X double fval;
- X struct ent *ent;
- X struct enode *enode;
- X char *sval;
- X struct range_s rval;
- X} YYSTYPE;
- Xextern YYSTYPE yylval;
- Xextern int VMS_read_raw; /*sigh*/
- X#else /* VMS */
- X#include "y.tab.h"
- X#endif /* VMS */
- X
- Xchar *strtof();
- X
- Xjmp_buf wakeup;
- Xjmp_buf fpe_buf;
- X
- Xstruct key {
- X char *key;
- X int val;
- X};
- X
- Xstruct key experres[] = {
- X#include "experres.h"
- X 0, 0};
- X
- Xstruct key statres[] = {
- X#include "statres.h"
- X 0, 0};
- X
- Xyylex ()
- X{
- X register char *p = line+linelim;
- X int ret;
- X while (isspace(*p)) p++;
- X if (*p == '\0') ret = -1;
- X else if (isalpha(*p)) {
- X char *tokenst = p;
- X register tokenl;
- X register struct key *tblp;
- X tokenl = 0;
- X /*
- X * This picks up either 1 or 2 alpha characters (a column) or
- X * tokens with at least three leading alphas and '_' or digits
- X * (a function or token or command or a range name)
- X */
- X while (isalpha(*p) || ((*p == '_') || isdigit(*p)) && (tokenl > 2)) {
- X p++;
- X tokenl++;
- X }
- X if (tokenl <= 2) { /* a COL is 1 or 2 char alpha
- X (but not pi, ln, fv, pv, if -- this should be fixed!) */
- X if (tokenl == 2 && tokenst[0] == 'p' && tokenst[1] == 'i') {
- X ret = K_PI;
- X } else if (tokenl == 2 && tokenst[0] == 'l' && tokenst[1] == 'n') {
- X ret = K_LN;
- X } else if (tokenl == 2 && tokenst[0] == 'f' && tokenst[1] == 'v') {
- X ret = K_FV;
- X } else if (tokenl == 2 && tokenst[0] == 'p' && tokenst[1] == 'v') {
- X ret = K_PV;
- X } else if (tokenl == 2 && tokenst[0] == 'i' && tokenst[1] == 'f') {
- X ret = K_IF;
- X
- X } else {
- X ret = COL;
- X yylval.ival = atocol (tokenst, tokenl);
- X }
- X } else {
- X ret = WORD;
- X for (tblp = linelim ? experres : statres; tblp->key; tblp++)
- X if (((tblp->key[0]^tokenst[0])&0137)==0
- X && tblp->key[tokenl]==0) {
- X register i = 1;
- X while (i<tokenl && ((tokenst[i]^tblp->key[i])&0137)==0)
- X i++;
- X if (i>=tokenl) {
- X ret = tblp->val;
- X break;
- X }
- X }
- X if (ret==WORD) {
- X struct range *r;
- X if (r = find_range(tokenst, tokenl,
- X (struct ent *)0, (struct ent *)0)) {
- X yylval.rval.left = r->r_left;
- X yylval.rval.right = r->r_right;
- X if (r->r_is_range)
- X ret = RANGE;
- X else
- X ret = VAR;
- X } else {
- X linelim = p-line;
- X yyerror ("Unintelligible word");
- X }
- X }
- X }
- X } else if ((*p == '.') || isdigit(*p)) {
- X double v = 0;
- X int temp;
- X char *nstart = p;
- X if (*p != '.') {
- X do v = v*10 + (double)(*p-'0');
- X while (isdigit(*++p));
- X }
- X if (*p=='.' || *p == 'e' || *p == 'E') {
- X ret = FNUMBER;
- X p = strtof(nstart, &yylval.fval);
- X } else {
- X /* A NUMBER must hold at least MAXROW and MAXCOL */
- X /* This is consistent with a short row and col in struct ent */
- X if (v > (double)32767 || v < (double)-32768) {
- X ret = FNUMBER;
- X yylval.fval = v;
- X } else {
- X temp = (int)v;
- X if((double)temp != v) {
- X ret = FNUMBER;
- X yylval.fval = v;
- X } else {
- X ret = NUMBER;
- X yylval.ival = temp;
- X }
- X }
- X }
- X } else if (*p=='"') {
- X char *ptr;
- X ptr = p+1;
- X while(*ptr && *ptr++ != '"');
- X ptr = xmalloc((unsigned)(ptr-p));
- X yylval.sval = ptr;
- X p += 1;
- X while (*p && *p!='"') *ptr++ = *p++;
- X *ptr = 0;
- X if (*p) p += 1;
- X ret = STRING;
- X } else if (*p=='[') {
- X while (*p && *p!=']') p++;
- X if (*p) p++;
- X linelim = p-line;
- X return yylex();
- X } else ret = *p++;
- X linelim = p-line;
- X return ret;
- X}
- X
- X
- X/*
- X * Given a token string starting with a symbolic column name and its valid
- X * length, convert column name ("A"-"Z" or "AA"-"ZZ") to a column number (0-N).
- X * Never mind if the column number is illegal (too high). The procedure's name
- X * and function are the inverse of coltoa().
- X *
- X * Case-insensitivity is done crudely, by ignoring the 040 bit.
- X */
- X
- Xint
- Xatocol (string, len)
- X char *string;
- X int len;
- X{
- X register int col;
- X
- X col = (string [0] & 0137) - 'A';
- X
- X if (len == 2) /* has second char */
- X col = ((col + 1) * 26) + ((string [1] & 0137) - 'A');
- X
- X return (col);
- X}
- X
- X
- X#ifdef SIMPLE
- X
- Xinitkbd()
- X{}
- X
- Xkbd_again()
- X{}
- X
- Xresetkbd()
- X{}
- X
- X#ifndef VMS
- X
- Xnmgetch()
- X{
- X return (toascii(getchar()));
- X}
- X
- X#else /* VMS */
- X
- Xnmgetch()
- X/*
- X This is not perfect, it doesn't move the cursor when goraw changes
- X over to deraw, but it works well enough since the whole sc package
- X is incredibly stable (loop constantly positions cursor).
- X
- X Question, why didn't the VMS people just implement cbreak?
- X
- X NOTE: During testing it was discovered that the DEBUGGER and curses
- X and this method of reading would collide (the screen was not updated
- X when continuing from screen mode in the debugger).
- X*/
- X{
- X short c;
- X static int key_id=0;
- X int status;
- X#define VMScheck(a) {if (~(status = (a)) & 1) VMS_MSG (status);}
- X
- X if (VMS_read_raw) {
- X VMScheck(smg$read_keystroke (&stdkb->_id, &c, 0, 0, 0));
- X }
- X else
- X c = getchar();
- X
- X switch (c) {
- X case SMG$K_TRM_LEFT: c = ctl('b'); break;
- X case SMG$K_TRM_RIGHT: c = ctl('f'); break;
- X case SMG$K_TRM_UP: c = ctl('p'); break;
- X case SMG$K_TRM_DOWN: c = ctl('n'); break;
- X default: c = c & 0x7f;
- X }
- X return (c);
- X}
- X
- X
- XVMS_MSG (status)
- Xint status;
- X/*
- X Routine to put out the VMS operating system error (if one occurs).
- X*/
- X{
- X#include <descrip.h>
- X char errstr[81], buf[120];
- X $DESCRIPTOR(errdesc, errstr);
- X short int length;
- X#define err_out(msg) fprintf (stderr,msg)
- X
- X/* Check for no error or standard error */
- X
- X if (~status & 1) {
- X status = status & 0x8000 ? status & 0xFFFFFFF : status & 0xFFFF;
- X if (SYS$GETMSG(status, &length, &errdesc, 1, 0) == SS$_NORMAL) {
- X errstr[length] = '\0';
- X sprintf (buf, "<0x%x> %s", status, errdesc.dsc$a_pointer);
- X err_out (buf);
- X }
- X else
- X err_out ("System error");
- X }
- X}
- X#endif /* VMS */
- X
- X#else /*SIMPLE*/
- X
- X#if defined(BSD42) || defined (SYSIII) || defined(BSD43)
- X
- X#define N_KEY 4
- X
- Xstruct key_map {
- X char *k_str;
- X char k_val;
- X char k_index;
- X};
- X
- Xstruct key_map km[N_KEY];
- X
- Xchar keyarea[N_KEY*30];
- X
- Xchar *tgetstr();
- Xchar *getenv();
- Xchar *ks;
- Xchar ks_buf[20];
- Xchar *ke;
- Xchar ke_buf[20];
- X
- X#ifdef TIOCSLTC
- Xstruct ltchars old_chars, new_chars;
- X#endif
- X
- Xchar dont_use[] = {
- X ctl('['), ctl('a'), ctl('b'), ctl('c'), ctl('e'), ctl('f'), ctl('g'), ctl('h'),
- X ctl('i'), ctl('j'), ctl('l'), ctl('m'), ctl('n'), ctl('p'), ctl('q'),
- X ctl('r'), ctl('s'), ctl('t'), ctl('u'), ctl('v'), ctl('w'), ctl('x'),
- X ctl('z'), 0
- X};
- X
- Xcharout(c)
- Xint c;
- X{
- X (void)putchar(c);
- X}
- X
- Xinitkbd()
- X{
- X register struct key_map *kp;
- X register i,j;
- X char *p = keyarea;
- X char *ktmp;
- X static char buf[1024]; /* Why do I have to do this again? */
- X
- X if (tgetent(buf, getenv("TERM")) <= 0)
- X return;
- X
- X km[0].k_str = tgetstr("kl", &p); km[0].k_val = ctl('b');
- X km[1].k_str = tgetstr("kr", &p); km[1].k_val = ctl('f');
- X km[2].k_str = tgetstr("ku", &p); km[2].k_val = ctl('p');
- X km[3].k_str = tgetstr("kd", &p); km[3].k_val = ctl('n');
- X ktmp = tgetstr("ks",&p);
- X if (ktmp) {
- X (void) strcpy(ks_buf, ktmp);
- X ks = ks_buf;
- X tputs(ks, 1, charout);
- X }
- X ktmp = tgetstr("ke",&p);
- X if (ktmp) {
- X (void) strcpy(ke_buf, ktmp);
- X ke = ke_buf;
- X }
- X
- X /* Unmap arrow keys which conflict with our ctl keys */
- X /* Ignore unset, longer than length 1, and 1-1 mapped keys */
- X
- X for (i = 0; i < N_KEY; i++) {
- X kp = &km[i];
- X if (kp->k_str && (kp->k_str[1] == 0) && (kp->k_str[0] != kp->k_val))
- X for (j = 0; dont_use[j] != 0; j++)
- X if (kp->k_str[0] == dont_use[j]) {
- X kp->k_str = (char *)0;
- X break;
- X }
- X }
- X
- X
- X#ifdef TIOCSLTC
- X (void)ioctl(fileno(stdin), TIOCGLTC, (char *)&old_chars);
- X new_chars = old_chars;
- X if (old_chars.t_lnextc == ctl('v'))
- X new_chars.t_lnextc = -1;
- X if (old_chars.t_rprntc == ctl('r'))
- X new_chars.t_rprntc = -1;
- X (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars);
- X#endif
- X}
- X
- Xvoid
- Xkbd_again()
- X{
- X if (ks)
- X tputs(ks, 1, charout);
- X
- X#ifdef TIOCSLTC
- X (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars);
- X#endif
- X}
- X
- Xvoid
- Xresetkbd()
- X{
- X if (ke)
- X tputs(ke, 1, charout);
- X
- X#ifdef TIOCSLTC
- X (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&old_chars);
- X#endif
- X}
- X
- Xnmgetch()
- X{
- X register int c;
- X register struct key_map *kp;
- X register struct key_map *biggest;
- X register int i;
- X int almost;
- X int maybe;
- X
- X static char dumpbuf[10];
- X static char *dumpindex;
- X
- X#ifdef SIGVOID
- X void time_out();
- X#else
- X int time_out();
- X#endif
- X
- X if (dumpindex && *dumpindex)
- X return (*dumpindex++);
- X
- X c = toascii(getchar());
- X biggest = 0;
- X almost = 0;
- X
- X for (kp = &km[0]; kp < &km[N_KEY]; kp++) {
- X if (!kp->k_str)
- X continue;
- X if (c == kp->k_str[kp->k_index]) {
- X almost = 1;
- X kp->k_index++;
- X if (kp->k_str[kp->k_index] == 0) {
- X c = kp->k_val;
- X for (kp = &km[0]; kp < &km[N_KEY]; kp++)
- X kp->k_index = 0;
- X return(c);
- X }
- X }
- X if (!biggest && kp->k_index)
- X biggest = kp;
- X else if (kp->k_index && biggest->k_index < kp->k_index)
- X biggest = kp;
- X }
- X
- X if (almost) {
- X (void) signal(SIGALRM, time_out);
- X (void) alarm(1);
- X
- X if (setjmp(wakeup) == 0) {
- X maybe = nmgetch();
- X (void) alarm(0);
- X return(maybe);
- X }
- X }
- X
- X if (biggest) {
- X for (i = 0; i<biggest->k_index; i++)
- X dumpbuf[i] = biggest->k_str[i];
- X if (!almost)
- X dumpbuf[i++] = c;
- X dumpbuf[i] = '\0';
- X dumpindex = &dumpbuf[1];
- X for (kp = &km[0]; kp < &km[N_KEY]; kp++)
- X kp->k_index = 0;
- X return (dumpbuf[0]);
- X }
- X
- X return(c);
- X}
- X
- X#endif
- X
- X#if defined(SYSV2) || defined(SYSV3)
- X
- Xinitkbd()
- X{
- X keypad(stdscr, TRUE);
- X}
- X
- Xvoid
- Xkbd_again()
- X{
- X keypad(stdscr, TRUE);
- X}
- X
- Xvoid
- Xresetkbd()
- X{
- X keypad(stdscr, FALSE);
- X}
- X
- Xnmgetch()
- X{
- X register int c;
- X
- X c = getch();
- X switch (c) {
- X case KEY_LEFT: c = ctl('b'); break;
- X case KEY_RIGHT: c = ctl('f'); break;
- X case KEY_UP: c = ctl('p'); break;
- X case KEY_DOWN: c = ctl('n'); break;
- X#ifdef KEY_C1
- X/* This stuff works for a wyse wy75 in ANSI mode under 5.3. Good luck. */
- X/* It is supposed to map the curses keypad back to the numeric equiv. */
- X case KEY_C1: c = '0'; break;
- X case KEY_A1: c = '1'; break;
- X case KEY_B2: c = '2'; break;
- X case KEY_A3: c = '3'; break;
- X case KEY_F(5): c = '4'; break;
- X case KEY_F(6): c = '5'; break;
- X case KEY_F(7): c = '6'; break;
- X case KEY_F(9): c = '7'; break;
- X case KEY_F(10): c = '8'; break;
- X case KEY_F0: c = '9'; break;
- X case KEY_C3: c = '.'; break;
- X case KEY_ENTER: c = ctl('m'); break;
- X#endif
- X default: c = toascii(c);
- X break;
- X }
- X return (c);
- X}
- X
- X#endif /* SYSV2 || SYSV3 */
- X
- X#endif /* SIMPLE */
- X
- X#ifdef SIGVOID
- Xvoid
- X#endif
- Xtime_out(signo)
- Xint signo;
- X{
- X#ifdef IEEE_MATH
- X (void)fpsetsticky((fp_except)0); /* Clear exception */
- X#endif /* IEEE_MATH */
- X longjmp(wakeup, -1);
- X}
- X
- X#ifdef SIGVOID
- Xvoid
- X#endif
- Xfpe_trap(signo)
- Xint signo;
- X{
- X longjmp(fpe_buf, 1);
- X}
- X
- X/*
- X * This converts a floating point number of the form
- X * [s]ddd[.d*][esd*] where s can be a + or - and e is E or e.
- X * to floating point.
- X * p is advanced.
- X */
- X
- Xchar *
- Xstrtof(p, res)
- Xregister char *p;
- Xdouble *res;
- X{
- X double acc;
- X int sign;
- X double fpos;
- X int exp;
- X int exps;
- X#ifdef SIGVOID
- X void (*sig_save)();
- X#else
- X int (*sig_save)();
- X#endif
- X
- X sig_save = signal(SIGFPE, fpe_trap);
- X if (setjmp(fpe_buf)) {
- X error("Floating point exception\n");
- X *res = 0.0;
- X (void) signal(SIGFPE, sig_save);
- X return(p);
- X }
- X acc = 0.0;
- X sign = 1;
- X exp = 0;
- X exps = 1;
- X if (*p == '+')
- X p++;
- X else if (*p == '-') {
- X p++;
- X sign = -1;
- X }
- X while (isdigit(*p)) {
- X acc = acc * 10.0 + (double)(*p - '0');
- X p++;
- X }
- X if (*p == 'e' || *p == 'E') {
- X p++;
- X if (*p == '+')
- X p++;
- X else if (*p == '-') {
- X p++;
- X exps = -1;
- X }
- X while(isdigit(*p)) {
- X exp = exp * 10 + (*p - '0');
- X p++;
- X }
- X }
- X if (*p == '.') {
- X fpos = 1.0/10.0;
- X p++;
- X while(isdigit(*p)) {
- X acc += (*p - '0') * fpos;
- X fpos *= 1.0/10.0;
- X p++;
- X }
- X }
- X if (*p == 'e' || *p == 'E') {
- X exp = 0;
- X exps = 1;
- X p++;
- X if (*p == '+')
- X p++;
- X else if (*p == '-') {
- X p++;
- X exps = -1;
- X }
- X while(isdigit(*p)) {
- X exp = exp * 10 + (*p - '0');
- X p++;
- X }
- X }
- X if (exp) {
- X if (exps > 0)
- X while (exp--)
- X acc *= 10.0;
- X else
- X while (exp--)
- X acc *= 1.0/10.0;
- X }
- X if (sign > 0)
- X *res = acc;
- X else
- X *res = -acc;
- X
- X (void) signal(SIGFPE, sig_save);
- X return(p);
- X}
- END_OF_FILE
- if test 13128 -ne `wc -c <'lex.c'`; then
- echo shar: \"'lex.c'\" unpacked with wrong size!
- fi
- # end of 'lex.c'
- fi
- if test -f 'psc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'psc.c'\"
- else
- echo shar: Extracting \"'psc.c'\" \(5741 characters\)
- sed "s/^X//" >'psc.c' <<'END_OF_FILE'
- X/* Sc parse routine
- X *
- X * usage psc options
- X * options:
- X * -L Left justify strings. Default is right justify.
- X * -r Assemble data into rows first, not columns.
- X * -R n Increment by n between rows
- X * -C n Increment by n between columns
- X * -n n Length of the row (column) should be n.
- X * -s v Top left location in the spreadsheet should be v; eg, k5
- X * -d c Use c as the delimiter between the fields.
- X * -k Keep all delimiters - Default is strip multiple delimiters to 1.
- X * -f suppress 'format' lines in output
- X *
- X * Author: Robert Bond
- X * $Revision: 6.8 $
- X */
- X
- X#include <ctype.h>
- X#include <stdio.h>
- X#include "sc.h"
- X
- X#define END 0
- X#define NUM 1
- X#define ALPHA 2
- X#define SPACE 3
- X#define EOL 4
- X
- Xextern char *optarg;
- Xextern int optind;
- Xchar *coltoa();
- Xchar *progname;
- X
- X#ifdef SYSV3
- Xextern void exit();
- X#else
- Xextern int exit();
- X#endif
- X
- Xint colfirst = 0;
- Xint r0 = 0;
- Xint c0 = 0;
- Xint rinc = 1;
- Xint cinc = 1;
- Xint leftadj = 0;
- Xint len = 20000;
- Xchar delim1 = ' ';
- Xchar delim2 = '\t';
- Xint strip_delim = 1;
- Xint drop_format = 0;
- Xint *fwidth;
- Xint *precision;
- Xint maxcols;
- X
- Xchar token[1000];
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X int curlen;
- X int curcol, coff;
- X int currow, roff;
- X int first;
- X int c;
- X register effr, effc;
- X int i,j;
- X register char *p;
- X
- X progname = argv[0];
- X while ((c = getopt(argc, argv, "rfLks:R:C:n:d:")) != EOF) {
- X switch(c) {
- X case 'r':
- X colfirst = 1;
- X break;
- X case 'L':
- X leftadj = 1;
- X break;
- X case 's':
- X c0 = getcol(optarg);
- X r0 = getrow(optarg);
- X break;
- X case 'R':
- X rinc = atoi(optarg);
- X break;
- X case 'C':
- X cinc = atoi(optarg);
- X break;
- X case 'n':
- X len = atoi(optarg);
- X break;
- X case 'd':
- X delim1 = optarg[0];
- X delim2 = 0;
- X break;
- X case 'k':
- X strip_delim = 0;
- X break;
- X case 'f':
- X drop_format = 1;
- X break;
- X default:
- X (void) fprintf(stderr,"Usage: %s [-rkfL] [-s v] [-R i] [-C i] [-n i] [-d c]\n", progname);
- X exit(1);
- X }
- X }
- X
- X if (optind < argc) {
- X (void) fprintf(stderr,"Usage: %s [-rL] [-s v] [-R i] [-C i] [-n i] [-d c]\n", progname);
- X exit(1);
- X }
- X
- X /* setup the spreadsheet arrays */
- X if (!growtbl(GROWNEW, 0, 0))
- X exit(1);
- X
- X curlen = 0;
- X curcol = c0; coff = 0;
- X currow = r0; roff = 0;
- X first = 1;
- X
- X while(1) {
- X
- X effr = currow+roff;
- X effc = curcol+coff;
- X
- X switch(scan()) {
- X case END:
- X if(drop_format) exit(0);
- X for (i = 0; i<maxcols; i++) {
- X if (precision[i])
- X (void) printf("format %s %d %d\n", coltoa(i),
- X fwidth[i], precision[i]+1);
- X }
- X exit(0);
- X case NUM:
- X first = 0;
- X (void) printf("let %s%d = %s\n", coltoa(effc), effr, token);
- X if (effc >= maxcols - 1)
- X { if (!growtbl(GROWCOL, 0, 0))
- X { (void) fprintf(stderr, "Invalid column used: %s\n", coltoa(effc));
- X continue;
- X }
- X }
- X i = 0;
- X j = 0;
- X p = token;
- X while (*p && *p != '.') {
- X p++; i++;
- X }
- X if (*p) {
- X p++; i++;
- X }
- X while (*p) {
- X p++; i++; j++;
- X }
- X if (precision[effc] < j)
- X precision[effc] = j;
- X if (fwidth[effc] < i)
- X fwidth[effc] = i;
- X break;
- X case ALPHA:
- X first = 0;
- X if (leftadj)
- X (void) printf("leftstring %s%d = \"%s\"\n", coltoa(effc),effr,token);
- X else
- X (void) printf("rightstring %s%d = \"%s\"\n",coltoa(effc),effr,token);
- X if (effc >= maxcols - 1)
- X { if (!growtbl(GROWCOL, 0, 0))
- X { (void) fprintf(stderr, "Invalid column used: %s\n", coltoa(effc));
- X continue;
- X }
- X }
- X i = strlen(token);
- X if (i > precision[effc])
- X precision[effc] = i;
- X break;
- X case SPACE:
- X if (first && strip_delim)
- X break;
- X if (colfirst)
- X roff++;
- X else
- X coff++;
- X break;
- X case EOL:
- X curlen++;
- X roff = 0;
- X coff = 0;
- X first = 1;
- X if (colfirst) {
- X if (curlen >= len) {
- X curcol = c0;
- X currow += rinc;
- X curlen = 0;
- X } else {
- X curcol += cinc;
- X }
- X } else {
- X if (curlen >= len) {
- X currow = r0;
- X curcol += cinc;
- X curlen = 0;
- X } else {
- X currow += rinc;
- X }
- X }
- X break;
- X }
- X }
- X}
- X
- Xscan()
- X{
- X register int c;
- X register char *p;
- X
- X p = token;
- X c = getchar();
- X
- X if (c == EOF)
- X return(END);
- X
- X if (c == '\n')
- X return(EOL);
- X
- X if (c == delim1 || c == delim2) {
- X if (strip_delim) {
- X while ((c = getchar()) && (c == delim1 || c == delim2))
- X ;
- X (void)ungetc(c, stdin);
- X }
- X return(SPACE);
- X }
- X
- X if (c == '\"') {
- X while ((c = getchar()) && c != '\"' && c != '\n' && c != EOF)
- X *p++ = c;
- X if (c != '\"')
- X (void)ungetc(c, stdin);
- X *p = 0;
- X return(ALPHA);
- X }
- X
- X while (c != delim1 && c != delim2 && c!= '\n' && c != EOF) {
- X *p++ = c;
- X c = getchar();
- X }
- X *p = 0;
- X (void)ungetc(c, stdin);
- X
- X p = token;
- X c = *p;
- X if (isdigit(c) || c == '.' || c == '-' || c == '+') {
- X while(isdigit(c) || c == '.' || c == '-' || c == '+' || c == 'e'
- X || c == 'E') {
- X c = *p++;
- X }
- X if (c == 0)
- X return(NUM);
- X else
- X return(ALPHA);
- X }
- X
- X return(ALPHA);
- X}
- X
- Xgetcol(p)
- Xchar *p;
- X{
- X register col;
- X
- X if (!p)
- X return(0);
- X while(*p && !isalpha(*p))
- X p++;
- X if (!*p)
- X return(0);
- X col = ((*p & 0137) - 'A');
- X if (isalpha(*++p))
- X col = (col + 1)*26 + ((*p & 0137) - 'A');
- X return(col);
- X}
- X
- Xgetrow(p)
- Xchar *p;
- X{
- X int row;
- X
- X if (!p)
- X return(0);
- X while(*p && !isdigit(*p))
- X p++;
- X if (!*p)
- X return(0);
- X if (sscanf(p, "%d", &row) != 1)
- X return(0);
- X return(row);
- X}
- X
- Xchar *
- Xcoltoa(col)
- Xint col;
- X{
- X static char rname[3];
- X register char *p = rname;
- X
- X if (col < 0 || col > 25*26)
- X (void) fprintf(stderr,"coltoa: invalid col: %d", col);
- X
- X if (col > 25) {
- X *p++ = col/26 + 'A' - 1;
- X col %= 26;
- X }
- X *p++ = col+'A';
- X *p = 0;
- X return(rname);
- X}
- X
- END_OF_FILE
- if test 5741 -ne `wc -c <'psc.c'`; then
- echo shar: \"'psc.c'\" unpacked with wrong size!
- fi
- # end of 'psc.c'
- fi
- if test -f 'xmalloc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xmalloc.c'\"
- else
- echo shar: Extracting \"'xmalloc.c'\" \(686 characters\)
- sed "s/^X//" >'xmalloc.c' <<'END_OF_FILE'
- X/*
- X * A safer saner malloc, for careless programmers
- X * $Revision: 6.8 $
- X */
- X
- X#include <stdio.h>
- X#include <curses.h>
- X#include "sc.h"
- X
- Xextern char *malloc();
- X
- X#ifdef SYSV3
- Xextern void free();
- Xextern void exit();
- X#endif
- X
- Xchar *
- Xxmalloc(n)
- Xunsigned n;
- X{
- Xregister char *ptr;
- X
- Xif ((ptr = malloc(n + sizeof(double))) == NULL)
- X fatal("xmalloc: no memory");
- X*((int *) ptr) = 12345; /* magic number */
- Xreturn(ptr + sizeof(double));
- X}
- X
- Xxfree(p)
- Xchar *p;
- X{
- Xif (p == NULL)
- X fatal("xfree: NULL");
- Xp -= sizeof(double);
- Xif (*((int *) p) != 12345)
- X fatal("xfree: storage not malloc'ed");
- Xfree(p);
- X}
- X
- Xfatal(str)
- Xchar *str;
- X{
- X deraw();
- X (void) fprintf(stderr,"%s\n", str);
- X exit(1);
- X}
- END_OF_FILE
- if test 686 -ne `wc -c <'xmalloc.c'`; then
- echo shar: \"'xmalloc.c'\" unpacked with wrong size!
- fi
- # end of 'xmalloc.c'
- fi
- echo shar: End of archive 4 \(of 6\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 5 6 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 6 archives.
- rm -f ark[1-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-